﻿using System;
using System.Collections.Generic;
using AOT;
using Newtonsoft.Json;
using UnityEngine;

namespace JSDBV2
{
    public class IndexedDBEx
    {
        public static void Init()
        {
#if UNITY_WEBGL && !UNITY_EDITOR
            IndexedDB.initJsStringToBuffer_v2();
#endif
        }
#if UNITY_WEBGL
        /******************** set ************************************/

        public static void SetFloat(string key, float v, Action<bool> back = null)
        {
            var pointer = AddDic_Back(IndexedDB.boolDic, back);
            IndexedDB.dbAddDataFloat_v2(pointer, key, v, IndexedDB.ResultStr_SetKey);
        }

        public static void SetInt(string key, int v, Action<bool> back = null)
        {
            var pointer = AddDic_Back(IndexedDB.boolDic, back);
            IndexedDB.dbAddDataInt_v2(pointer, key, v, IndexedDB.ResultStr_SetKey);
        }

        public static void SetString(string key, string v, Action<bool> back = null)
        {
            var pointer = AddDic_Back(IndexedDB.boolDic, back);
            IndexedDB.dbAddData_v2(pointer, key, v, IndexedDB.ResultStr_SetKey);
        }
        
        public static void SetFloatArray(string key, float[] v, Action<bool> back = null)
        {
            var pointer = AddDic_Back(IndexedDB.boolDic, back);
            IndexedDB.dbAddDataFloatArray_v2(pointer, key, v, v.Length,IndexedDB.ResultStr_SetKey);
        }

        /******************** get ************************************/

        static int AddDic_Back<T>(Dictionary<int, Action<T>> dic, Action<T> back)
        {
            int pointer = 0;
            if (back!=null && !back.Target.Equals(null))
            {
                pointer = back.GetHashCode();
                if (dic.ContainsKey(pointer))
                {
                    dic[pointer] += back;
                }
                else
                {
                    dic[pointer] = back;
                }
            }

            return pointer;
        }
        
        // static int AddDic_Back<T>(Dictionary<int, Action<T[]>> dic, Action<string> back)
        // {
        //     int pointer = 0;
        //     if (back!=null && !back.Target.Equals(null))
        //     {
        //         pointer = back.GetHashCode();
        //         if (dic.ContainsKey(pointer))
        //         {
        //             dic[pointer] += back;
        //         }
        //         else
        //         {
        //             dic[pointer] = back;
        //         }
        //     }
        //
        //     return pointer;
        // }

        public static void GetString(string key, Action<string> back)
        {
            var pointer = AddDic_Back(IndexedDB.strDic, back);
            IndexedDB.dbGetData_v2(pointer, key,  IndexedDB.ResultStr);
        }

        public static void GetFloat(string key, Action<float> back)
        {
            var pointer = AddDic_Back(IndexedDB.floatDic, back);
            IndexedDB.dbGetDataFloat_v2(pointer, key,  IndexedDB.Resultfloat);
        }

        public static void GetInt(string key, Action<int> back)
        {
            var pointer = AddDic_Back(IndexedDB.intDic, back);
            IndexedDB.dbGetDataInt_v2(pointer, key,  IndexedDB.ResultInt);
        }
        
        public static void GetFloatArray(string key, Action<float[]> back)
        {
            var pointer = AddDic_Back(IndexedDB.floatArrayDic, back);
            IndexedDB.dbGetDataFloatArray_v2(pointer, key,  IndexedDB.ResultfloatArray);
        }

        /******************** del ************************************/
        public static void DeleteKey(string key)
        {
            IndexedDB.dbDelData_v2(key);
        }
#else
        public static void SetFloat(string key, float v, Action<bool> back = null)
        {
            PlayerPrefs.SetFloat(key, v);
            back?.Invoke(true);
        }

        public static void SetInt(string key, int v, Action<bool> back = null)
        {
            PlayerPrefs.SetInt(key, v);
            back?.Invoke(true);
        }

        public static void SetString(string key, string v, Action<bool> back = null)
        {
            PlayerPrefs.SetString(key, v);
            back?.Invoke(true);
        }
        
        public static void SetFloatArray(string key, float[] v, Action<bool> back = null)
        {
            var arr=  JsonConvert.SerializeObject(v);
            PlayerPrefs.SetString(key, arr);
            back?.Invoke(true);
        }

        public static void GetFloat(string key, Action<float> back)
        {
            var result = PlayerPrefs.GetFloat(key, 0);
            back?.Invoke(result);
        }

        public static void GetInt(string key, Action<int> back)
        {
            var result = PlayerPrefs.GetInt(key, 0);
            back?.Invoke(result);
        }
        
        public static void GetString(string key, Action<string> back)
        {
            var result = PlayerPrefs.GetString(key, "");
            back?.Invoke(result);
        }

        public static void GetFloatArray(string key, Action<float[]> back)
        {
            var result = PlayerPrefs.GetString(key, "[]");
            var arr=  JsonConvert.DeserializeObject<float[]>(result);
            back?.Invoke(arr);
        }

        public static void DeleteKey(string key)
        {
            PlayerPrefs.DeleteKey(key);
        }
#endif
    }
}